package mn.idax.exchange.otc.util;

import com.google.common.collect.Maps;
import mn.idax.exchange.common.CalendarUtil;
import mn.idax.exchange.otc.enums.ResponseEnum;
import mn.idax.exchange.otc.exception.IdaxException;
import mn.idax.exchange.otc.interceptor.OtcSecurityInterceptor;
import mn.idax.exchange.otc.service.impl.MemoryService;
import org.slf4j.LoggerFactory;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.util.Date;
import java.util.Map;

/**
 * @program: open-api
 * @description: SignUtils
 * @author: zhuwei
 * @create: 2019/05/27 11:00
 */
public class SignUtils {

    private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(OtcSecurityInterceptor.class);

    /**
     * 验证签名
     * @param sign
     * @param content
     * @param privateSecret
     * @return
     */
    public static boolean verifSign(String sign,String content,String privateSecret){
        if(sign.equals(SignUtils.hmacSha256(content,privateSecret))){
            return true;
        }
        return false;
    }

    /**
     * sha256_HMAC加密
     *
     * @param message
     *            消息
     * @param secret
     *            秘钥
     * @return 加密后字符串
     */
    public static String hmacSha256(String message, String secret) {
        String hash = "";
        try {
            String data = message;
            Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
            SecretKeySpec secret_key = new SecretKeySpec(secret.getBytes("UTF-8"), "HmacSHA256");

            sha256_HMAC.init(secret_key);
            byte[] bytes = sha256_HMAC.doFinal(data.getBytes());
            hash =  byteArrayToHexString(bytes);
        } catch (Exception e) {
            LOGGER.warn("hmacSha256 exception:"+ e.getMessage());
        }
        return hash;
    }

    /**
     * 将加密后的字节数组转换成字符串
     * @param b
     * @return
     */
    private static String byteArrayToHexString(byte[] b) {
        StringBuilder hs = new StringBuilder();
        String stmp;
        for (int n = 0; b!=null && n < b.length; n++) {
            stmp = Integer.toHexString(b[n] & 0XFF);
            if (stmp.length() == 1) {
                hs.append('0');
            }
            hs.append(stmp);
        }
        return hs.toString().toLowerCase();
    }

    /**
     * 验证签名
     * @param paramMap
     * @return
     * @throws Exception
     */
    public static boolean idaxApiVierfySign(Map paramMap)throws Exception{

        String apiKey = paramMap.get("key").toString();
        Long timestamp =Long.valueOf(paramMap.get("timeStamp").toString());
        String sign = paramMap.get("sign").toString();
        long systeTime = DateUtils.getCalendarToDate(CalendarUtil.getUTCDate(new Date())).getTime();
        /**3分(min)=180000毫秒(ms)***/
        long userfulTime = 180000;
        /**判断缓存中是否存在key**/
        Object systemApiKey = MemoryService.SYSTEMSETTINGMAP.get(apiKey);
        if(systemApiKey == null ){
            throw new IdaxException(ResponseEnum.KEY_DOES_NOT_EXIST.getRespCode(),ResponseEnum.KEY_DOES_NOT_EXIST.getRespMsg());
        }
        long time = systeTime - timestamp;
        /**允许时间差在120秒**/
        if( time > userfulTime ){
            throw new IdaxException(ResponseEnum.TIMESTAMP_EXPIRATED.getRespCode(),ResponseEnum.TIMESTAMP_EXPIRATED.getRespMsg());
        }

        paramMap.remove("sign");
        String secretKey = systemApiKey.toString();
        String param = ObjectUtils.sortMap(paramMap);
        /**验证签名**/
        if(!SignUtils.verifSign(sign,param,secretKey)){
            throw new IdaxException(ResponseEnum.SIGNATURE_MISMATCH.getRespCode(),ResponseEnum.SIGNATURE_MISMATCH.getRespMsg());
        }
        return true;
    }

}
